package com.xxxtea.entity;

import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.xxxtea.common.BaseEnum;
import com.xxxtea.common.anno.AutowiredUserId;
import com.xxxtea.common.anno.DeserializeOnly;
import com.xxxtea.config.converter.BaseEnumDeserializer;
import com.xxxtea.dto.Location;
import com.xxxtea.mpe.annotation.Constraint;
import com.xxxtea.mpe.annotation.ExtendQuery;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;

import java.util.Date;
import java.util.List;

/**
 * 跑腿任务实体类
 *
 * 用于存储跑腿任务信息，包括：
 * - 任务基本信息（标题、描述、报酬等）
 * - 任务位置信息（起点、目的地、距离等）
 * - 任务状态管理（待接单、进行中、已完成等）
 * - 发布者和接单者信息关联
 * - 任务进度和异常管理
 *
 * 使用MyBatis-Plus注解进行数据库映射
 * 使用Swagger注解进行API文档生成
 *
 * @author badman
 * @since 1.0.0
 */
@Data
@ApiModel("跑腿任务")
@TableName(autoResultMap = true)
public class Task {

	/**
	 * 主键ID
	 * 使用自增策略
	 */
	@ApiModelProperty("主键")
	@TableId(value = "id", type = IdType.AUTO)
	private Integer id;

	/**
	 * 发布者ID
	 * 自动注入当前用户ID
	 * 关联User表
	 */
	@ApiModelProperty("发布者ID")
	@AutowiredUserId
	@Constraint(referenceClass = User.class)
	private Integer publisherId;

	/**
	 * 接单者ID
	 * 关联User表，使用别名acceptor
	 */
	@ApiModelProperty("接单者ID")
	@Constraint(referenceClass = User.class, tableAlias = "acceptor")
	private Integer acceptorId;

	/**
	 * 任务标题
	 * 支持模糊查询
	 */
	@TableField(condition = SqlCondition.LIKE)
	@ApiModelProperty("任务标题")
	private String name;

	/**
	 * 任务描述
	 * 任务的详细描述信息
	 */
	@ApiModelProperty("任务描述")
	private String description;

	/**
	 * 报酬金额
	 * 任务的报酬
	 */
	@ApiModelProperty("报酬金额")
	private Double reward;

	/**
	 * 校区
	 * 任务所在校区，支持模糊查询
	 */
	@TableField(condition = SqlCondition.LIKE)
	@ApiModelProperty("校区")
	private String campus;

	/**
	 * 任务地点
	 * 任务的起点地址
	 */
	@ApiModelProperty("任务地点")
	private String originAddress;

	/**
	 * 任务目的地
	 * 任务的目标地址
	 */
	@ApiModelProperty("任务目的地")
	private String destAddress;

	/**
	 * 距离
	 * 起点到目的地的距离
	 */
	@ApiModelProperty("距离")
	private Double distance;

	/**
	 * 起点经纬度
	 * 任务起点的地理位置坐标
	 */
	@ApiModelProperty("起点经纬度")
	private Location originLocation;

	/**
	 * 目的地经纬度
	 * 任务目的地的地理位置坐标
	 */
	@ApiModelProperty("目的地经纬度")
	private Location destLocation;

	/**
	 * 任务类型
	 * 1-代购 2-代取快递 3-代办事务
	 * 使用枚举类型管理
	 */
	@ApiModelProperty("任务类型 1-代购 2-代取快递 3-代办事务")
	@JsonDeserialize(using = BaseEnumDeserializer.class)
	private Type type;

	/**
	 * 任务状态
	 * 1-待接单 2-进行中 3-已完成 4-已取消 5-已关闭
	 * 使用枚举类型管理
	 */
	@ApiModelProperty("任务状态 1-待接单 2-进行中 3-已完成 4-已取消 5-已关闭")
	@JsonDeserialize(using = BaseEnumDeserializer.class)
	private Status status;

	/**
	 * 截止时间
	 * 任务的截止时间
	 */
	@ApiModelProperty("截止时间")
	private Date deadline;

	/**
	 * 预计分钟数
	 * 任务预计完成时间（分钟）
	 */
	@ApiModelProperty("预计分钟数")
	private Integer estimatedTime;

	/**
	 * 进度百分比
	 * 任务完成进度（0-100）
	 */
	@ApiModelProperty("进度百分比")
	private Integer progress;

	/**
	 * 是否异常
	 * 0-正常 1-异常
	 * 使用枚举类型管理
	 */
	@ApiModelProperty("是否异常 0-正常 1-异常")
	@JsonDeserialize(using = BaseEnumDeserializer.class)
	private IsAbnormal isAbnormal;

	/**
	 * 异常原因
	 * 任务异常的原因说明
	 */
	@ApiModelProperty("异常原因")
	private String abnormalReason;

	/**
	 * 接单时间
	 * 任务被接单的时间
	 */
	@ApiModelProperty("接单时间")
	private Date acceptTime;

	/**
	 * 创建时间
	 * 自动填充插入时间
	 */
	@ApiModelProperty("创建时间")
	@TableField(fill = FieldFill.INSERT)
	private Date createTime;

	/**
	 * 更新时间
	 * 自动填充插入和更新时间
	 */
	@ApiModelProperty("更新时间")
	@TableField(fill = FieldFill.INSERT_UPDATE)
	private Date updateTime;

	/**
	 * 发布者昵称
	 * 扩展查询字段，关联用户表获取昵称
	 */
	@ExtendQuery(referenceClass = User.class, targetColumn = "nickname")
	private String publisherName;

	/**
	 * 发布者头像
	 * 扩展查询字段，关联用户表获取头像，启用资源处理
	 */
	@ExtendQuery(referenceClass = User.class, targetColumn = "avatar", enableResource = true)
	private String publisherAvatar;

	/**
	 * 接单者昵称
	 * 扩展查询字段，关联用户表获取昵称，使用别名acceptor
	 */
	@ExtendQuery(referenceClass = User.class, targetColumn = "nickname", alias = "acceptor")
	private String acceptorName;

	/**
	 * 接单者头像
	 * 扩展查询字段，关联用户表获取头像，使用别名acceptor，启用资源处理
	 */
	@ExtendQuery(referenceClass = User.class, targetColumn = "avatar", alias = "acceptor", enableResource = true)
	private String acceptorAvatar;

	/**
	 * 起始距离
	 * 非数据库字段，用于显示与用户的距离
	 */
	@TableField(exist = false)
	private String startDistance;

	/**
	 * 发布者信息
	 * 非数据库字段，用于关联查询发布者详细信息
	 */
	@TableField(exist = false)
	private User publisher;

	/**
	 * 评价列表
	 * 非数据库字段，用于关联查询评价信息
	 */
	@TableField(exist = false)
	private List<Review> reviewList;

	/**
	 * 任务阶段列表
	 * 非数据库字段，用于关联查询任务阶段信息
	 */
	@TableField(exist = false)
	private List<TaskStage> taskStages;

	/**
	 * 是否为我发布的任务
	 * 非数据库字段，用于前端显示
	 */
	@TableField(exist = false)
	private Boolean publishedByMe;

	/**
	 * 是否为我接单的任务
	 * 非数据库字段，用于前端显示
	 */
	@TableField(exist = false)
	private Boolean acceptedByMe;

	/**
	 * 最小距离
	 * 仅用于反序列化，查询条件
	 */
	@DeserializeOnly
	private Double minDistance;

	/**
	 * 最大距离
	 * 仅用于反序列化，查询条件
	 */
	@DeserializeOnly
	private Double maxDistance;

	/**
	 * 最小报酬
	 * 仅用于反序列化，查询条件
	 */
	@DeserializeOnly
	private Double minReward;

	/**
	 * 最大报酬
	 * 仅用于反序列化，查询条件
	 */
	@DeserializeOnly
	private Double maxReward;

	/**
	 * 是否计算距离
	 * 仅用于反序列化，查询条件
	 */
	@DeserializeOnly
	private boolean calDistance;

	/**
	 * 状态列表
	 * 仅用于反序列化，查询条件
	 */
	@DeserializeOnly
	private List<Integer> statusList;

	/**
	 * 任务类型枚举
	 * 定义任务的各种类型
	 */
	@Getter
	@AllArgsConstructor
	public enum Type implements BaseEnum<Type> {
		/**
		 * 代购类型
		 */
		Type1(1, "代购"),
		/**
		 * 代取快递类型
		 */
		Type2(2, "代取快递"),
		/**
		 * 代办事务类型
		 */
		Type3(3, "代办事务");

		private final Integer value;
		private final String label;
	}

	/**
	 * 任务状态枚举
	 * 定义任务的各种状态
	 */
	@Getter
	@AllArgsConstructor
	public enum Status implements BaseEnum<Status> {
		/**
		 * 待接单状态
		 */
		PENDING(1, "待接单"),
		/**
		 * 进行中状态
		 */
		PROGRESS(2, "进行中"),
		/**
		 * 已完成状态
		 */
		FINISH(3, "已完成"),
		/**
		 * 已取消状态
		 */
		CANCEL(4, "已取消"),
		/**
		 * 已关闭状态
		 */
		CLOSE(5, "已关闭");

		private final Integer value;
		private final String label;
	}

	/**
	 * 是否异常枚举
	 * 定义任务的异常状态
	 */
	@Getter
	@AllArgsConstructor
	public enum IsAbnormal implements BaseEnum<IsAbnormal> {
		/**
		 * 正常状态
		 */
		NO(0, "正常"),
		/**
		 * 异常状态
		 */
		YES(1, "异常");

		private final Integer value;
		private final String label;
	}
}
